home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
NXPlot3d
/
Source
/
token.lm
< prev
next >
Wrap
Text File
|
1993-10-12
|
3KB
|
135 lines
%{
/*
token.lm
This file defines the tokens that the Expression grammar is built on. To
fully understand this file, you will need to understand lex. The basic
idea is that lex scans a text stream and breaks that stream up into tokens
which are then fed to the grammar (defined in yacc). Whitespace is ignored
so the grammar is just fed a steady stream of significant tokens.
*/
/*
* These are the routines lex calls to get another character as it parses.
* By default they are macros which read from stdin. We toss the default
* macro definitions and supply our own versions of these, which will feed
* lex characters from the expression string we are parsing.
*/
#undef input
#undef unput
#undef output
static int input();
static void unput(char c);
static void output(char c);
#import <stdlib.h>
#import <string.h>
#import <math.h>
#import "exprDefs.h"
#import "y.tab.h"
/* global which holds the string we are parsing */
static const char *CurrText;
/* glue to get rid of compiler warnings */
extern yylook(), yyback();
static int yywrap();
%}
DIGIT ([0-9])
EXP ([Ee][+-]?[0-9]+)
%%
[ \t\n]+ { /* whitespace - we ignore it */
;
}
{DIGIT}+ { /* an integer */
yylval.integer = atoi(yytext);
return INTEGER;
}
(({DIGIT}+"."{DIGIT}*{EXP}?)|([+-]?{DIGIT}*"."{DIGIT}+{EXP}?)|({DIGIT}+{EXP})) { /* a float */
yylval.real = atof(yytext);
return NUMBER;
}
{DIGIT}+"#"[a-zA-Z0-9]+ { /* a radix number */
int radix;
register int mult = 1;
register char *c, *stop;
register unsigned int accum = 0;
register int charVal;
sscanf( yytext, "%d#", &radix );
for( stop = yytext; *stop++ != '#'; ); /* skip the pound sign */
for( c = yytext+yyleng-1; c >= stop; c--, mult *= radix ) {
if( *c >= '0' && *c <= '9' )
charVal = *c - '0';
else if( *c >= 'A' && *c <= 'Z' )
charVal = *c - 'A' + 10;
else
charVal = *c - 'a' + 10;
accum += mult * charVal;
}
yylval.real = accum;
return NUMBER;
}
pi { /* the constant pi */
yylval.real = M_PI;
return NUMBER;
}
e { /* the constant e */
yylval.real = M_E;
return NUMBER;
}
[-+*/%^(),] { /* a single char that must be recognized */
return yytext[0];
}
[A-Za-z_][A-Za-z_0-9]* { /* an identifier */
yylval.string = NXZoneMalloc(NXDefaultMallocZone(), yyleng+1);
bcopy(yytext, yylval.string, yyleng);
yylval.string[yyleng] = '\0';
return IDENTIFIER;
}
. { /* other garbage chars (last rule is the default) */
yylval.character = yytext[0];
return BADCHAR;
}
%%
/* inits the global string to the one we will parse */
void _EXPPrepareToScan(const char *text) {
CurrText = text;
}
/* tells lex there's really no more input when we're done */
static int yywrap() {
return 1;
}
/* returns the next char of the string we're parsing */
static int input() {
return *CurrText++;
}
/* lets lex back up one char in the string we're parsing */
static void unput(char c) {
--CurrText;
}
/* called by lex when it wants to output a char. This should never happen. */
static void output(char c) {
fprintf(stderr, "lex output function called with char '%c'\n", c);
}